package es.deusto.ingenieria.BlWhSquares;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import es.deusto.ingenieria.is.search.algorithms.Node;
import es.deusto.ingenieria.is.search.algorithms.heuristic.EvaluationFunction;
import es.deusto.ingenieria.is.search.algorithms.heuristic.HeuristicSearchMethod;
import es.deusto.ingenieria.is.search.formulation.Operator;
import es.deusto.ingenieria.is.search.formulation.Problem;
import es.deusto.ingenieria.is.search.formulation.State;

public class OnlineHillClimbing extends HeuristicSearchMethod {

	public OnlineHillClimbing(EvaluationFunction arg0) {
		super(arg0);
		// TODO Auto-generated constructor stub
	}

	@Override
	public Node search(Problem problem, State initialState) {
       
		
		
		Node firstNode = new Node(initialState);;
	
		
		boolean solutionFound = false;			
		while (!solutionFound ) {			
					
			//If the first node contains a problem's final state
			if (problem.isFinalState(firstNode.getState())) {
				
				solutionFound = true;
						
			} else {
				
			Node	mejorNodoSucesor = this.expand(firstNode, problem); 
			if( ! problem.isFullyObserved(mejorNodoSucesor.getState())){
				mejorNodoSucesor.setState(problem.gatherPercepts(mejorNodoSucesor.getState()));
			}
			double firstNodeH = getEvaluationFunction().calculateH(firstNode) ;
			double mejorNodoH= getEvaluationFunction().calculateH(mejorNodoSucesor);
			System.out.println("Valor H actual"+firstNodeH);
			System.out.println("Valor H del Mejor"+mejorNodoH);
			
			if(firstNodeH <= mejorNodoH ){
				
				solutionFound = true;
			}else{
				firstNode= mejorNodoSucesor;
			}
			
				
				
			}
		}
		
		// If the problem is solved
		if (solutionFound) {
			//Return the first node as it contains the problem's final state
			return firstNode;
		//If the problem is not solved
		} else {
			//return null
			return null;
		}

}
	protected Node expand(Node node, Problem problem) { //, List<State> expandedStates
		
		Node successorNode = null;
		State currentState = null;
		State successorState = null;
		Node nodoMejor = null;

		//If neither node or problem are null
		if (node != null && problem != null) {
			//Get the node's state.
			currentState = node.getState();
			//Remove current state from the list of generated states.
			
			//Insert current state to the list of generated states.
			//expandedStates.add(currentState);
			//If the state is not null
			if (currentState != null) {
				//Go over the list of problem operators
				double mejorSucesor=0;
				double  sucesor=0;
				
				for (Operator operator : problem.getOperators()) {
					
					successorState = operator.apply(currentState);
					
					if (successorState != null){
						
						successorNode = new Node(successorState);
						
						sucesor=getEvaluationFunction().calculateH(successorNode);
						
						if( sucesor > mejorSucesor) {
							nodoMejor = successorNode;
							
							nodoMejor.setOperator(operator.getName());
							mejorSucesor = sucesor;
						}
										
						
									
					}
					
				}
				nodoMejor.setParent(node);
				nodoMejor.setH(super.getEvaluationFunction().calculateH(node));
				nodoMejor.setDepth(node.getDepth() + 1);
			}
		}
		
		return nodoMejor;
	}

}


